import * as _ from 'lodash';

import {
	builtIn, localType
} from '../constants/index';

export function traverse (parameters: ReferenceSchema | ReferenceSchema[], hasContext: Set<string>) {
	for (const parameter of [].concat.call([], parameters)) {
		if (parameter?.schema === undefined) continue;

		const { schema } = parameter;
		const $ref = schema?.$ref || schema?.items?.$ref;
		const content = handleStrRef($ref || '');
		if (content !== 'any') hasContext.add(content);
	}
}

export function replaceUrlQurey (url: string) {
	return (url || '').replace(/\{([\w]+)\}/g, (content) => '$' + content);
}

export function addQueryReplaceUrl (url: string, parameters: string | string[]) {
	if (parameters.includes('query')) {
		return (url || '').replace(/\{([\w]+)\}/g, (_tmpl, content) => '${query.' + content + '}');
	} else {
		return (url || '').replace(/\{([\w]+)\}/g, (_tmpl, content) => '${' + content + '}');
	}
}

export function defaultFnSort (prev: ParameterFace, next: ParameterFace) {
	return ~~next.required - ~~prev.required;
}

/**
 * example: OrderStatus
 * @param property string
 * @param letter string
 * @returns string
 */
export function startEnumCase (property: string, letter: string) {
	return _.startCase(property) + _.startCase(letter);
}

/**
 * example: OrderStatus
 * @param letter string
 * @returns string
 */
export function startClassCase (letter?: string) {
	return _.startCase(letter).replace(/\s/g, '');
}

/**
 * clean extra letters, example:
 * #/definitions/User,
 * remain last letter User
 * @param reference string
 * @returns string
 */
export function splitCleanExtra (reference: string) {
	if (localType.includes(reference)) {
		return reference;
	} else {
		const prefix = reference?.split('/').pop() as string;

		if (builtIn.includes(prefix as string)) {
			return 'Record<string, any>';
		}

		return 'LocalDate' === prefix
			? 'string' : startClassCase(cleanBrackets(prefix));
	}
}

export function handleStrRef (reference: string) {
	return splitCleanExtra(reference);
}

/**
 * 用于处理字符串中的特殊字符 [«»]；
 * 并生成 A_B_C 形式字符串，示例: A_B_C；
 * 以 any 类型，进行兜底处理
 * @param originalRef string
 * @returns string
 */
export function cleanBrackets (originalRef: string) {
	// definitions: { HashMap«string,string» : Object }
	if (/(\w+),(\w+)/g.test(originalRef)) {
		originalRef = originalRef.replace(/(\w+),(\w+)/g, RegExp.$1);
	}
	return (originalRef || 'any').replace(/»/g, '').replace(/«/g, '_');
}

/**
 * 过滤掉在 url 中已使用的参数
 * @param url string
 * @param parameters ParameterFace []
 * @returns
 */
export function filterParameters (url: string, parameters: ParameterFace[]) {
	const __ob__: AvailableParameter = Object.create(null);
	for (const parameter of parameters) {
		const { name } = parameter;
		if (name && !url?.includes(name)) {
			__ob__[parameter.name] = parameter;
		}
	}

	return Object.keys(__ob__).length ? __ob__ : null;
}
